<template>
  <div class="file-list" v-loading="loading" element-loading-text="加载中...">
    <div class="files-grid">
      <div
        v-for="item in fileList"
        :key="item.path"
        class="file-item"
        @dblclick="handleDblClick(item)"
        @contextmenu.prevent="handleContextMenu($event, item)"
      >
        <el-icon class="file-icon" :size="60" :color="getIconColor(item)">
          <component :is="getFileIcon(item)" />
        </el-icon>
        <div class="file-name" :title="item.name">{{ item.name }}</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  Document,
  Folder,
  Picture,
  VideoPlay,
  Headset,
  Files,
  Film,
  Collection,
  Document as DocIcon,
  Grid
} from '@element-plus/icons-vue'
import type { OSSFile, OSSDirectory } from '../types'
import { useAclStore } from '/@/store/modules/acl'

defineProps<{
  fileList: (OSSFile | OSSDirectory)[]
  loading?: boolean
}>()

const emit = defineEmits<{
  (e: 'dblclick', item: OSSFile | OSSDirectory): void
  (e: 'contextmenu', event: MouseEvent, item: OSSFile | OSSDirectory): void
}>()

const aclStore = useAclStore()

// 文件类型映射
const fileTypeMap = {
  // 图片文件
  image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'],
  // 视频文件
  video: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'],
  // 音频文件
  audio: ['mp3', 'wav', 'ogg', 'flac', 'm4a', 'wma'],
  // 文档文件
  document: ['doc', 'docx', 'pdf', 'txt', 'rtf', 'odt'],
  // 压缩文件
  archive: ['zip', 'rar', '7z', 'tar', 'gz'],
  // 表格文件
  spreadsheet: ['xls', 'xlsx', 'csv'],
  // 演示文件
  presentation: ['ppt', 'pptx'],
  // 代码文件
  code: ['js', 'ts', 'html', 'css', 'java', 'py', 'php', 'vue', 'jsx', 'tsx']
}

// 颜色映射
const colorMap = {
  folder: '#409eff',     // 文件夹 - 蓝色
  image: '#67c23a',      // 图片 - 绿色
  video: '#e6a23c',      // 视频 - 橙色
  audio: '#f56c6c',      // 音频 - 红色
  document: '#8e44ad',   // 文档 - 紫色
  archive: '#2c3e50',    // 压缩文件 - 深灰色
  spreadsheet: '#27ae60', // 表格文件 - 深绿色
  presentation: '#d35400', // 演示文件 - 深橙色
  code: '#16a085',       // 代码文件 - 青色
  default: '#909399'     // 默认颜色 - 灰色
}

// 获取文件图标
const getFileIcon = (item: OSSFile | OSSDirectory) => {
  if ('type' in item && item.type === 'folder') {
    return Folder
  }

  if (!('name' in item)) return Document

  const extension = item.name.split('.').pop()?.toLowerCase() || ''

  if (fileTypeMap.image.includes(extension)) {
    return Picture
  }
  if (fileTypeMap.video.includes(extension)) {
    return VideoPlay
  }
  if (fileTypeMap.audio.includes(extension)) {
    return Headset
  }
  if (fileTypeMap.document.includes(extension)) {
    return DocIcon
  }
  if (fileTypeMap.archive.includes(extension)) {
    return Files
  }
  if (fileTypeMap.spreadsheet.includes(extension)) {
    return Grid
  }
  if (fileTypeMap.presentation.includes(extension)) {
    return Collection
  }
  if (fileTypeMap.code.includes(extension)) {
    return Film
  }

  return Document
}

// 获取图标颜色
const getIconColor = (item: OSSFile | OSSDirectory) => {
  if ('type' in item && item.type === 'folder') {
    return colorMap.folder
  }

  if (!('name' in item)) return colorMap.default

  const extension = item.name.split('.').pop()?.toLowerCase() || ''

  if (fileTypeMap.image.includes(extension)) {
    return colorMap.image
  }
  if (fileTypeMap.video.includes(extension)) {
    return colorMap.video
  }
  if (fileTypeMap.audio.includes(extension)) {
    return colorMap.audio
  }
  if (fileTypeMap.document.includes(extension)) {
    return colorMap.document
  }
  if (fileTypeMap.archive.includes(extension)) {
    return colorMap.archive
  }
  if (fileTypeMap.spreadsheet.includes(extension)) {
    return colorMap.spreadsheet
  }
  if (fileTypeMap.presentation.includes(extension)) {
    return colorMap.presentation
  }
  if (fileTypeMap.code.includes(extension)) {
    return colorMap.code
  }

  return colorMap.default
}

const handleDblClick = (item: OSSFile | OSSDirectory) => {
  // 检查权限
  const hasViewPermission = aclStore.getPermission.includes('system:oss:view')
  const hasPreviewPermission = aclStore.getPermission.includes('system:oss:doPreview')
  
  if ('type' in item && item.type === 'folder') {
    if (hasViewPermission) {
      emit('dblclick', item)
    }
  } else {
    if (hasPreviewPermission) {
      emit('dblclick', item)
    }
  }
}

const handleContextMenu = (event: MouseEvent, item: OSSFile | OSSDirectory) => {
  emit('contextmenu', event, item)
}
</script>

<style scoped lang="scss">
.file-list {
  flex: 1;
  overflow-y: auto;
  position: relative;
  height: 100%;

  // 自定义 loading 样式
  :deep(.el-loading-mask) {
    background-color: rgba(255, 255, 255, 0.7);
  }
}

.files-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 16px;
  padding: 8px;
}

.file-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px;
  border-radius: 4px;
  cursor: pointer;
  user-select: none;

  &:hover {
    background-color: #e6f1fc;
  }

  .file-icon {
    margin-bottom: 8px;
    font-size: 60px;
  }

  .file-name {
    width: 100%;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13px;
    padding: 0 4px;
  }
}
</style> 